/*
 *------------------------------------------------------------------------------
 * sched.h - definitions for the scheduler module
 *
 * The scheduler module owns global data structures that implement process
 * scheduling, most of which are maintained in the scheduler module's code and
 * some which are pushed off to a separate module due to size (i.e. process
 * related code).
 *
 * 9-20-2008, Forhad Ahmed
 *------------------------------------------------------------------------------
 */

#ifndef SCHED_H
#define SCHED_H

#include "list.h"
#include "proc.h"


/*
 * Scheduler constants
 *
 *   SCHED_QUANTUM - number of timeslices a process gets to execute before being
 *                   rescheduled.
 *   SCHED_PAUSE   - number of milliseconds to pause after execution of each
 *                   process instruction (speed of simulation).
 */
#define SCHED_QUANTUM 3
#define SCHED_PAUSE   200000


/*
 * Core scheduler structures:
 *
 *   stime - global scheduler time; increments per atomic instruction execution
 *   runq - queue for processes that are eligible to run
 *   waitq - queue for processes that are sleeping or resource blocked
 *   resourceq - queue of resource objects
 *   sleep_wait - count of processes (in waitq) and sleeping
 *   resource_wait - count of processes (in waitq) and awaiting a resource
 */
int   stime;
list *runq;
list *waitq;
list *resourceq;
int   sleep_wait;
int   resource_wait;


/*
 * Scheduler shared resource object
 *
 *   link    - list node linking resource objects. MUST be the first element.
 *   name    - name of the shared resource object.
 *   owner   - pcb of the owner process that has the lock on this resource.
 *   blocked - list of processes that are blocked on this resource.
 */
typedef struct resource_t {
    node  link;
    char *name;
    proc *owner;
    list  blocked;
} resource;


/*
 * Process states as seen by the scheduler:
 *
 *   SCHED_READY - process is in runq and waiting to be executed
 *   SCHED_RUNNING - process is at head of the runq and currently executing
 *   SCHED_SLEEP_WAIT - process is in waitq and waiting for timer wakeup
 *   SCHED_RESOURCE_WAIT - process is in waitq waiting for a resource unblock
 */
enum {
    SCHED_READY,
    SCHED_RUNNING,
    SCHED_SLEEP_WAIT,
    SCHED_RESOURCE_WAIT
};


/*
 * schedule(proc *p)
 *
 *   Core scheduler function.  Takes a pcb, prepares its scheduling related
 *   fields, and *places it in a desired position in the runq*.  How the runq
 *   position is chosen for the pcb is the essence of scheduling.  It can be
 *   done in a variety of ways.  For example, we can choose to always put the
 *   pcb at the end of the runq (FCFS scheduling) or always at the beginning of
 *   the runq (LCFS scheduling).  PCB's can also be inserted in the runq in a
 *   sorted order based on any of its fields, including the 'priority' field,
 *   which would simulate priority scheduling.
 */
void schedule(proc *p);

#endif /* SCHED_H */
